package main

import (
	"fmt"
	"runtime"
	"unsafe"
)

type CMemData1 struct {
	// size - offset - align
	b int32 // 4-0-4
	d int64 // 8-8-8
	c int8 // 1-16-1
	a bool // 1-17-1
	e byte // 1-18-1 // CMemData1的size 8的最小倍数24
}

type CMemData2 struct {
	// size/offset/align
	b int32 // 4-0-4
	c int8 // 1-4-1
	a bool // 1-5-1
	e byte // 1-6-1 //CMemData2的size 最后一位补齐，4的最小倍数 8
}

type CMemData3 struct {
	// size - offset - align
	c int16 // 2-0-2
	a bool // 1-2-1
	e byte // 1-3-1 // CMemData3的size 最后一位补齐，2的最小倍数 4
}
// 腾讯的面试题：
type S struct {
	A uint32 // 0
	B uint64 // 8
	C uint64 // 16
	D uint64 // 32
	E struct{} // 8的最小整数倍 40
	// 结构体中如果有空结构（struct{}，大小是0），如果空结构放在末尾，也会按照对齐字节大小进行一次填充处理
}


func main() {

	/**
	system info: darwin,arm64
	CMemData1's Size=24 Alignof=8
	CMemData2's Size=8 Alignof=4
	CMemData3's Size=4 Alignof=2
	在我64位的机器上得到的CMemData1是按照8字节对齐的（d占8字节），CMemData2则又是4字节（b占4字节），最后一个CMemData3数据则又是2字节（c占2字节）。
	另外，如果在结构体中如果有空结构（struct{}，大小是0），如果空结构放在末尾，也会按照对齐字节大小进行一次填充处理
	*/

	fmt.Printf("system info: %s,%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Printf("CMemData1's Size=%d Alignof=%d\n", unsafe.Sizeof(CMemData1{}), unsafe.Alignof(CMemData1{}))
	fmt.Printf("CMemData1 size/offset/align, b:%d-%d-%d,d:%d-%d-%d,c:%d-%d-%d,a:%d-%d-%d,e:%d-%d-%d \n",
		unsafe.Sizeof(CMemData1{}.b),unsafe.Offsetof(CMemData1{}.b),unsafe.Alignof(CMemData1{}.b),
		unsafe.Sizeof(CMemData1{}.d),unsafe.Offsetof(CMemData1{}.d),unsafe.Alignof(CMemData1{}.d),
		unsafe.Sizeof(CMemData1{}.c),unsafe.Offsetof(CMemData1{}.c),unsafe.Alignof(CMemData1{}.c),
		unsafe.Sizeof(CMemData1{}.a),unsafe.Offsetof(CMemData1{}.a),unsafe.Alignof(CMemData1{}.a),
		unsafe.Sizeof(CMemData1{}.e),unsafe.Offsetof(CMemData1{}.e),unsafe.Alignof(CMemData1{}.e))
	fmt.Printf("CMemData2's Size=%d Alignof=%d\n", unsafe.Sizeof(CMemData2{}), unsafe.Alignof(CMemData2{}))
	fmt.Printf("CMemData2 size/offset/align, b:%d-%d-%d,c:%d-%d-%d,a:%d-%d-%d,e:%d-%d-%d \n",
		unsafe.Sizeof(CMemData2{}.b),unsafe.Offsetof(CMemData2{}.b),unsafe.Alignof(CMemData2{}.b),
		unsafe.Sizeof(CMemData2{}.c),unsafe.Offsetof(CMemData2{}.c),unsafe.Alignof(CMemData2{}.c),
		unsafe.Sizeof(CMemData2{}.a),unsafe.Offsetof(CMemData2{}.a),unsafe.Alignof(CMemData2{}.a),
		unsafe.Sizeof(CMemData2{}.e),unsafe.Offsetof(CMemData2{}.e),unsafe.Alignof(CMemData2{}.e))

	fmt.Printf("CMemData3's Size=%d Alignof=%d\n", unsafe.Sizeof(CMemData3{}), unsafe.Alignof(CMemData3{}))
	fmt.Printf("CMemData3 size/offset/align,c:%d-%d-%d,a:%d-%d-%d,e:%d-%d-%d \n",
		unsafe.Sizeof(CMemData3{}.c),unsafe.Offsetof(CMemData3{}.c),unsafe.Alignof(CMemData3{}.c),
		unsafe.Sizeof(CMemData3{}.a),unsafe.Offsetof(CMemData3{}.a),unsafe.Alignof(CMemData3{}.a),
		unsafe.Sizeof(CMemData3{}.e),unsafe.Offsetof(CMemData3{}.e),unsafe.Alignof(CMemData3{}.e))
	// 腾讯的面试题：
	fmt.Println("腾讯的面试题：")
	fmt.Println(unsafe.Offsetof(S{}.E))
	fmt.Println(unsafe.Sizeof(S{}.E))
	fmt.Println(unsafe.Sizeof(S{}))
}

